﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Toom.CellularAutomata.Model
{
	public abstract class CARuleStatic
	{
		protected CAField field;
		public abstract int CalculateTransform( int x, int y );

		public static List<CAGameType> GetAllGameTypes()
		{
			List<CAGameType> list = new List<CAGameType>();
			list.Add( CAGameType.CONWAY );
			list.Add( CAGameType.NEC_MIN );
			list.Add( CAGameType.NEC_MAX );
			list.Add( CAGameType.NEC_MEDIAN );
			list.Add( CAGameType.SWAP_ZEROS_AND_TWOS );
			return list;
		}
	}



	public enum CAGameType
	{
		NONE,
		CUSTOM,
		CONWAY,
		NEC_MIN,
		NEC_MAX,
		NEC_MEDIAN,
		SWAP_ZEROS_AND_TWOS
	}


	public class CARuleStaticSumEightNeighborsConway : CARuleStatic
	{
		public CARuleStaticSumEightNeighborsConway(CAField f)
		{
			this.field = f;
		}

		public override int CalculateTransform(int x, int y)
		{
			int newVal;
			int sum = 0;

			for (int j = -1; j <= 1; j++)
				for (int i = -1; i <= 1; i++)
				{
					if (i == 0 && j == 0) continue;

					int d = field.GetDataAt( x+i, y+j );
					if (d == 1)
						sum++;
				}

			newVal = 0;
			int curVal = field.GetDataAt(x,y);

			if (curVal == 0)
			{
				if (sum == 3)
					newVal = 1;
			}
			else if (curVal == 1)
			{
				if (sum == 3 || sum == 2)
					newVal = 1;
			}
			else
				//throw new Exception("data is not 0 or 1.... hmmmmm.....");
				newVal = curVal;

			return newVal;
		}
	}//class RuleSumEightNeighborsConway



	public class CARuleStaticMinimumNEC : CARuleStatic
	{
		public CARuleStaticMinimumNEC( CAField f )
		{
			this.field = f;
		}

		public override int CalculateTransform( int x, int y )
		{
			//CACalculator c = new CACalculator(field);
			int min = int.MaxValue;

			int d = field.GetDataAt( x, y+1 );
			if ( d < min )
				min=d;

			d = field.GetDataAt( x+1, y );
			if ( d < min )
				min = d;

			d = field.GetDataAt( x,y );
			if ( d < min )
				min = d;

			return min;
		}
	}//class RuleMinimumNEC


	class CARuleStaticMaximumNEC : CARuleStatic
	{
		public CARuleStaticMaximumNEC( CAField f )
		{
			this.field = f;
		}

		public override int CalculateTransform( int x, int y )
		{
			int max = int.MinValue;

			int d = field.GetDataAt( x, y+1 );
			if ( d > max )
				max = d;

			d = field.GetDataAt( x+1, y );
			if ( d > max )
				max = d;

			d = field.GetDataAt( x,y );
			if ( d > max )
				max = d;

			return max;
		}
	}//class RuleMaximumNEC 



	public class CARuleStaticMedianNEC : CARuleStatic
	{
		public CARuleStaticMedianNEC( CAField f )
		{
			this.field = f;
		}

		public override int CalculateTransform( int x, int y )
		{
			List<int> values = new List<int>();

			int d = field.GetDataAt( x, y+1 );
			values.Add( d );

			d = field.GetDataAt( x+1, y );
			values.Add( d );

			d = field.GetDataAt( x,y );
			values.Add( d );

			values.Sort();

			return values[1];
		}
	}//class RuleMaximumNEC 



	public class CARuleStaticSwapTwosAndZeros : CARuleStatic
	{
		public CARuleStaticSwapTwosAndZeros( CAField f )
		{
			this.field = f;
		}

		public override int CalculateTransform( int x, int y )
		{
			int newVal;

			newVal = field.GetDataAt( x,y );

			if ( newVal == 2 )
				newVal = 0;
			else if ( newVal == 0 )
				newVal = 2;

			return newVal;
		}
	}//class RuleMaximumNEC 



}//ns
